package com.daqian.chance.mybatis.plus.generator;


import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.InjectionConfig;
import com.baomidou.mybatisplus.generator.config.*;
import com.baomidou.mybatisplus.generator.config.converts.MySqlTypeConvert;
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
import com.baomidou.mybatisplus.generator.config.rules.DbColumnType;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class GeneratorMain {
    final static String projectPath = "E:\\workspace2\\my\\chance\\chance-example\\chance-admin-example";
    final static String javaPath = "\\src\\main\\java";
    final static String packagePath = "\\com\\daqian\\chance\\example\\admin\\modules\\system\\";
    final static String packageParent = "com.daqian.chance.example.admin.modules.system";


    public static void main(String[] args) {

        AutoGenerator mpg = new AutoGenerator();

        // 全局配置
        GlobalConfig gc = new GlobalConfig();
        // 输出文件路径
        gc.setOutputDir(projectPath + javaPath);
        // 是否覆盖文件
        gc.setFileOverride(true);
        // 开启 activeRecord 模式
        gc.setActiveRecord(false);
        // XML 二级缓存
        gc.setEnableCache(false);
        // XML ResultMap
        gc.setBaseResultMap(true);
        // XML columnList
        gc.setBaseColumnList(true);
        // 是否打开输出目录    默认值：true
        gc.setOpen(false);
        // 作者
        gc.setAuthor("daqian");
        gc.setBaseColumnList(true);

        mpg.setGlobalConfig(gc);

        // 数据源配置
        DataSourceConfig dsc = new DataSourceConfig();
        dsc.setDbType(DbType.MYSQL);

        dsc.setUrl("jdbc:mysql://47.100.218.223:3306/chance_cloud?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull&allowMultiQueries=true&useSSL=true");
        dsc.setUsername("daqian");
        dsc.setPassword("dadaqian1!2ASD");
        dsc.setDriverName("com.mysql.cj.jdbc.Driver");
        dsc.setTypeConvert(new MySqlTypeConvert() {
            // 自定义数据库表字段类型转换【可选】
            @Override
            public DbColumnType processTypeConvert(GlobalConfig globalConfig, String fieldType) {
                System.out.println("转换类型：" + fieldType);
                if (fieldType.toLowerCase().contains("datetime")) {
                    return DbColumnType.DATE;
                } else if (fieldType.toLowerCase().contains("int(11) unsigned")) {
                    return DbColumnType.LONG;
                }
                return (DbColumnType) super.processTypeConvert(globalConfig, fieldType);
            }
        });
        mpg.setDataSource(dsc);

        // 策略配置
        StrategyConfig strategy = new StrategyConfig()
                // 此处可以修改为您的表前缀
//                .setTablePrefix(new String[]{"member_"})
                // 表名生成策略
                .setNaming(NamingStrategy.underline_to_camel)
                // 列名生成策略
                .setColumnNaming(NamingStrategy.underline_to_camel)
                // 需要生成的表
//                .setInclude("elasticSearch")
                // 自定义 controller 父类
                .setSuperControllerClass("com.daqian.chance.common.base.BaseController")
                // 自定义 service 父类
                .setSuperServiceClass(null)
                // 自定义 service 实现类父类
                .setSuperServiceImplClass(null)
                // 自定义 mapper 父类
                .setSuperMapperClass("com.daqian.chance.mybatis.plus.base.ChanceBaseMapper")
                // 自定义 entity 父类
//                .setSuperEntityClass(null)
                // 【实体】是否为构建者模型（默认 false）
                .setEntityBuilderModel(true)
                // 【实体】是否为lombok模型（默认 false）
                .setEntityLombokModel(true)
                // 设置rest风格controller
                .setRestControllerStyle(true)
                // Boolean类型字段是否移除is前缀处理
                .setEntityBooleanColumnRemoveIsPrefix(true);
        mpg.setStrategy(strategy);

        // 包配置
        PackageConfig pc = new PackageConfig()
                .setParent(packageParent)
                .setController("controller")
                .setService("service")
                .setServiceImpl("service.impl")
                .setEntity("po.entity")
                .setMapper("mapper")
                .setXml("mapper.impl");
        mpg.setPackageInfo(pc);

        mpg.setTemplateEngine(new FreemarkerTemplateEngine());

        //自定义配置
        injectionConfig(mpg);

        //指定自定义模板路径, 位置：/resources/templates/entity.java.ftl(或者是.vm)
        TemplateConfig templateConfig = new TemplateConfig();
        templateConfig.setController("templates/controller.java");
        templateConfig.setService("templates/service.java");
        templateConfig.setServiceImpl("templates/serviceImpl.java");
        mpg.setTemplate(templateConfig);

        // 执行生成
        mpg.execute();
    }


    /**
     * 自定义配置
     *
     * @param mpg
     */
    private static void injectionConfig(AutoGenerator mpg) {
        // 自定义配置
        InjectionConfig cfg = new InjectionConfig() {
            @Override
            public void initMap() {
                Map<String, Object> map = new HashMap<>();
//                map.put("packageParent", this.getConfig().getGlobalConfig().getAuthor() + "-mp");
                map.put("packageParent", packageParent);
                this.setMap(map);
            }
        };

        // 自定义输出配置
        List<FileOutConfig> focList = new ArrayList<>();
        // 自定义dto
        addOutputPath(focList, "dto.java.ftl", "po/dto", "DTO");
        // 自定义req
        addOutputPath(focList, "req.java.ftl", "po/req", "Req");
        // 自定义vo
        addOutputPath(focList, "vo.java.ftl", "po/vo", "VO");

        cfg.setFileOutConfigList(focList);
        mpg.setCfg(cfg);
    }

    private static void addOutputPath(List<FileOutConfig> focList, String templatePath, String packageSuffix, String fileSuffix) {
        // 自定义配置会被优先输出
        focList.add(new FileOutConfig("templates/custom/" + templatePath) {
            @Override
            public String outputFile(TableInfo tableInfo) {
                // 自定义输出文件名 ， 如果你 Entity 设置了前后缀、此处注意 xml 的名称会跟着发生变化！！
                return projectPath + javaPath + packagePath + packageSuffix
                        + "/" + tableInfo.getEntityName() + fileSuffix + StringPool.DOT_JAVA;
            }
        });
    }

}
